from flask import Flask
from app.config import Config
from app.utils.ros_utils import ROSUtils
from flask_socketio import SocketIO

# 创建全局SocketIO实例
socketio = SocketIO()

def create_app(config_class=Config):
    """应用工厂函数"""
    app = Flask(__name__)
    app.config.from_object(config_class)
    
    # 初始化SocketIO
    socketio.init_app(
        app, 
        cors_allowed_origins="*", 
        async_mode='threading',
        logger=app.config.get('DEBUG', False),
        engineio_logger=app.config.get('DEBUG', False)
    )
    
    # 初始化ROS工具
    ros_utils = ROSUtils(
        app.config.get('LOG_DIR', '/tmp/logs'),
        app.config.get('MAX_LOG_FILES', 10)
    )
    
    # 注册蓝图 - 注意顺序和URL前缀
    from app.routes.main_routes import main_bp
    from app.routes.msg_routes import init_msg_routes
    from app.routes.arm_routes import init_arm_routes
    from app.routes.ros_routes import init_ros_routes
    from app.routes.cabin_routes import init_cabin_routes
    
    # 注册主蓝图（没有URL前缀）
    app.register_blueprint(main_bp)
    
    # 初始化并注册其他蓝图
    msg_bp = init_msg_routes(socketio)
    arm_bp = init_arm_routes(ros_utils)
    cabin_bp = init_cabin_routes(ros_utils)
    ros_bp = init_ros_routes(ros_utils, app.config.get('ROS_LAUNCH_FILES', []))
    
    # 为API蓝图添加统一前缀
    app.register_blueprint(msg_bp, url_prefix='/api/msg')
    app.register_blueprint(arm_bp, url_prefix='/api/arm') 
    app.register_blueprint(cabin_bp, url_prefix='/api/cabin') 
    app.register_blueprint(ros_bp, url_prefix='/api/ros')
    
    # 注册错误处理
    register_error_handlers(app)
    
    # 注册SocketIO事件处理
    register_socketio_handlers()
    
    # 存储实例到app上下文
    app.ros_utils = ros_utils
    app.socketio = socketio
    
    return app

def register_error_handlers(app):
    """注册错误处理器"""
    
    @app.errorhandler(404)
    def not_found_error(error):
        return {'code': 404, 'message': '资源未找到'}, 404
    
    @app.errorhandler(500)
    def internal_error(error):
        app.logger.error(f'服务器错误: {error}')
        return {'code': 500, 'message': '服务器内部错误'}, 500
    
    @app.errorhandler(400)
    def bad_request_error(error):
        return {'code': 400, 'message': '请求参数错误'}, 400
    
    @app.errorhandler(405)
    def method_not_allowed_error(error):
        return {'code': 405, 'message': '请求方法不允许'}, 405

def register_socketio_handlers():
    """注册SocketIO事件处理器"""
    
    @socketio.on('connect')
    def handle_connect():
        print('客户端连接成功')
        # 发送当前所有数据给新连接的客户端
        try:
            from app.services.msg_service import MsgService
            msg_service = MsgService(socketio)
            # socketio.emit('ros_initial_data', msg_service.get_latest_data())
        except Exception as e:
            print(f'发送初始数据失败: {e}')
    
    @socketio.on('disconnect')
    def handle_disconnect():
        print('客户端断开连接')
    
    @socketio.on('client_ready')
    def handle_client_ready(data):
        """处理客户端就绪事件"""
        print(f'客户端就绪: {data}')
        socketio.emit('server_ready', {'message': '服务器已准备好'})